package com.lanou.quanttrade.stock.service;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.lanou.quanttrade.member.javabean.Member;
import com.lanou.quanttrade.stock.javabean.*;
import com.lanou.quanttrade.stock.mapper.BiasInfoMapper;
import com.lanou.quanttrade.stock.mapper.MemberDailyStrategyMapper;
import com.lanou.quanttrade.stock.mapper.StockBasicInfoMapper;
import com.lanou.quanttrade.utils.javabean.RestObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpSession;
import java.text.SimpleDateFormat;
import java.util.*;

@Service
public class StockService {
    @Autowired
    private BiasInfoMapper biasInfoMapper;
    @Autowired
    private StockBasicInfoMapper stockBasicInfoMapper;
    private SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
    @Autowired
    private MemberDailyStrategyMapper memberDailyStrategyMapper;
    /**
     * 首页推荐股票
     * @return
     */
    public RestObject recommendStocksThroughBias() {
        //1、从6日乖离率清洗结果中，获取推荐的前三只股票信息
        List<BiasInfo> biasInfoList = biasInfoMapper.getBiasInfosThroughBias();
        if(biasInfoList==null || biasInfoList.size()==0)
            return RestObject.ERROR("没有推荐股票");
        //2、根据股票代码，查询三只股票信息
        List<String> tscodeList = new ArrayList<>();
        for (BiasInfo biasInfo : biasInfoList) {
            tscodeList.add(biasInfo.getStockcode());
        }
        List<StockBasicInfo> stockBasicInfos = stockBasicInfoMapper.getStockBasicInfosThroughTscodes(tscodeList);
        if(stockBasicInfos==null || stockBasicInfos.size()==0)
            return RestObject.ERROR("没有推荐股票基本信息");
        List<HomeSellUIBean> homeSellUIBeans = new ArrayList<>();
        for (StockBasicInfo sbi : stockBasicInfos) {
            homeSellUIBeans.add(
                    new HomeSellUIBean(sbi.getTscode(),sbi.getStockname(),sbi.getIndustry())
            );
        }
        //3、将信息封装并返回
        return RestObject.OK("查询到推荐股票",homeSellUIBeans);
    }


    /**
     * 根据股票代码，查询股票echarts图表展示所需内容
     * @param stockcode
     * @return
     */
    public RestObject getImgData(String stockcode) {
        //1、根据stockcode查询 该股票仅7个自然日的 6日乖离率综合信息（该数据已经被清洗归因）
        List<BiasInfo> biasInfoList = biasInfoMapper.getBiasInfosThroughStockcode(stockcode);
        if(biasInfoList==null || biasInfoList.size()==0){
            //可能stockcode中没有带SZ或SH，需要去基础表查询
            StockBasicInfo sbi = stockBasicInfoMapper.getStockBasicInfoThroughStockcode(stockcode);
            if(sbi==null || sbi.getTscode()==null)
                return RestObject.ERROR("没有该股票的基本信息和乖离率信息");
            biasInfoList = biasInfoMapper.getBiasInfosThroughStockcode(sbi.getTscode());
            if(biasInfoList==null || biasInfoList.size()==0)
                return RestObject.ERROR("没有该股票的乖离率信息");
        }

        //2、将查询结果转为指定json数据
        HashMap<String, Object> dataMap = new HashMap<>();
        HashMap<String, Object> xAxisMap = new HashMap<>();

        //填充x轴信息相关内容
        List<String> tradedateList = new ArrayList<>();
        for (BiasInfo bi : biasInfoList) {
            String tradedate = bi.getTradedate();
            tradedateList.add(
                    tradedate.substring(0,4)+"-"+tradedate.substring(4,6)+
                            "-"+tradedate.substring(6)
            );
        }
        xAxisMap.put("data",tradedateList);
        dataMap.put("xAxis",xAxisMap);

        //填充y轴信息
        ArrayList<Object> series = new ArrayList<>();
        HashMap<String, Object> seriesMap = new HashMap<>();
        seriesMap.put("type","candlestick");
        List<Float[]> dataList = new ArrayList<>();
        float min=Float.MAX_VALUE,max=Float.MIN_VALUE;
        for (BiasInfo bi : biasInfoList) {
            Float[] temp = new Float[4];
            temp[0]=bi.getStockopen();
            temp[1]=bi.getStockclose();
            Float high = bi.getHigh();
            Float low = bi.getLow();
            temp[2]=high;
            temp[3]=low;
            min = low<min?low:min;
            max = high>max?high:max;
            dataList.add(temp);
        }
        seriesMap.put("data",dataList);
        series.add(seriesMap);
        dataMap.put("series",series);

        //设置y轴最小值和最大值
        HashMap<String, Object> yAxisMap = new HashMap<>();
        yAxisMap.put("type","value");
        yAxisMap.put("min",min);
        yAxisMap.put("max",max);
        dataMap.put("yAxis",yAxisMap);

        RestObject restObject = new RestObject();
        restObject.setCode(1);
        restObject.setMsg("业务成功");
        restObject.setData(dataMap);
        //3、封装并返回
        return restObject;
    }

    /**
     * 保存策略信息，并将策略 id 返回给前端
     * @param memberDailyStrategy
     * @param session
     * @return
     */
    public RestObject saveMemberDailyStrategy(MemberDailyStrategy memberDailyStrategy, HttpSession session) {
        //1、获得并填充登录用户id
        Member member = (Member) session.getAttribute("member");
        if(member==null)
            return RestObject.ERROR("请先登录");
        memberDailyStrategy.setMid(member.getId());
        //2、填充起始和结束日期
        String[] date = memberDailyStrategy.getDate();
        if(date==null || date.length==0){
            //用户没有设置上市区间，我们就设置默认的：从19900101~今
            memberDailyStrategy.setStartdate("19900101");
            memberDailyStrategy.setEnddate(sdf.format(new Date()));
        }else{
            //用户设置了上市区间，按设置的进行
            memberDailyStrategy.setStartdate(date[0].replaceAll("-",""));
            memberDailyStrategy.setEnddate(date[1].replaceAll("-",""));
        }
        //3、保存数据
        memberDailyStrategyMapper.saveMemberDailyStrategy(memberDailyStrategy);
        //4、封装返回结果，并将策略id返回
        HashMap<String, Object> map = new HashMap<>();
        map.put("id",memberDailyStrategy.getId());
        return RestObject.OK("添加策略成功",map);
    }

    /**
     * 保存某个策略的 策略展示列表，并将保存结果返回给前端
     * @param memberDailyStrategyTable
     * @return
     */
    public RestObject saveMemberDailyStrategyTable(MemberDailyStrategyTable memberDailyStrategyTable) {
        //1、将id赋给sid，防止数据混乱
        if(memberDailyStrategyTable.getId()==null)
            return RestObject.ERROR("策略信息保存异常，策略表保存失败");
        memberDailyStrategyTable.setSid(memberDailyStrategyTable.getId());
        memberDailyStrategyTable.setId(null);
        //2、先保存策略表整体
        memberDailyStrategyMapper.saveMemberDailyStrategyTable(memberDailyStrategyTable);
        //3、得到策略表主键后，按策略表主键，保存策略表的一系列表头数据
        memberDailyStrategyMapper.saveMemberDailyStrategyTableItems(memberDailyStrategyTable);
        //4、返回保存结果
        return RestObject.OK("策略表保存成功");
    }

    /**
     * 查询该用户的策略列表，并返回前端
     * @param session
     * @return
     */
    public RestObject getMemberDailyStrategysThroughMid(HttpSession session) {
        //1、获得并填充登录用户id
        Member member = (Member) session.getAttribute("member");
        if(member==null)
            return RestObject.ERROR("请先登录");
        //2、通过mid查询该用户所有的 策略展示列表和列表的列表项
        List<MemberDailyStrategyTable> memberDailyStrategyTableList
                = memberDailyStrategyMapper.getMemberDailyStrategysThroughMid(member.getId());
        //3、将结果进行返回
        return RestObject.OK("查询策略列表成功",memberDailyStrategyTableList);
    }

    /**
     * 乖离率分页展示&策略列表分页展示
     * @param paramMap
     * @return
     */
    public RestObject getMemberDailyStrategyDatas(Map<String, String> paramMap) {
        //1、获取参数&分页插件
        //获取策略展示列表ID
        Integer id = Integer.parseInt(paramMap.get("id"));
        //获取当前展示第几页
        Integer pageNum = Integer.parseInt(paramMap.get("pageNum"));
        //获取一页展示记录数
        Integer pageSize = Integer.parseInt(paramMap.get("pageSize"));
        //2、判断是乖离率展示还是其他策略列表展示
        if(id.intValue()==0){
            //乖离率展示
            //分页
            PageHelper.startPage(pageNum,pageSize);
            List<Map> biasInfos = biasInfoMapper.getBiasInfos();
            PageInfo<Map> pi = new PageInfo<>(biasInfos);
            HashMap<String, Object> map = new HashMap<>();
            map.put("rows",pi.getTotal());
            map.put("list",pi.getList());
            return RestObject.OK("乖离率查询完成",map);
        }else{
            //其他策略列表展示
            MemberDailyStrategy memberDailyStrategy = memberDailyStrategyMapper.getMemberDailyStrategyThroughTbId(id);
            if(memberDailyStrategy==null || memberDailyStrategy.getId()==null)
                return RestObject.ERROR("该策略已经不存在，请重新尝试");
            //分页
            PageHelper.startPage(pageNum,pageSize);
            List<Map> mapList = memberDailyStrategyMapper.getMrDailyResultsThroughParam(memberDailyStrategy);
            PageInfo<Map> pi = new PageInfo<>(mapList);
            HashMap<String, Object> map = new HashMap<>();
            map.put("rows",pi.getTotal());
            map.put("list",pi.getList());
            return RestObject.OK("策略查询完成",map);
        }
    }
}
